/*
 * @Date: 2023-04-26 16:31:56
 * @Description:工具集
 * @LastEditors: hujingyang
 * @Author: hujingyang
 * @FilePath: \largeScreenDataVisualization\src\common\utils.ts
 * @IDE: Created by VScode.
 */

import { ElLoading, ElMessage, MessageHandler } from "element-plus";
import dayjs from "dayjs";
import router from "@/router";

let timer: any = null;
type CallbackFn = (item?: any) => void;

/**
 * 防抖函数 - 立即执行
 * @param Callback 需要执行的函数
 * @param wait - 拦截 wait 时间内相同的请求
 */
export function debounceImmediately(Callback: CallbackFn, wait = 500) {
  return function (..._argus: any) {
    if (timer) clearTimeout(timer);
    const callNow = !timer;
    timer = setTimeout(() => (timer = null), wait);
    if (callNow) Callback && Callback(..._argus); //当有值才会执行
  };
}
/**
 * 防抖函数 - 延迟执行版
 * @param Callback 需要执行的函数
 * @param wait - 拦截 wait 时间内相同的请求
 */
export function debounceLazy(Callback: CallbackFn, wait = 500) {
  return function (..._argus: any) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      Callback && Callback(..._argus); //当有值才会执行
      timer = null;
    }, wait);
  };
}

/**设置深拷贝，仅支持 简单对象 */
export function deepCopy(data: any) {
  if (!data) return data;
  return JSON.parse(JSON.stringify(data));
}

/**快捷时间选择类型 */
export interface ShortCuts {
  /**时间提示文字 */
  text: string;
  /**当前预设的时间 */
  value: () => [start: Date, end: Date];
}

/**时间快捷选择数组 */
export function shortcutsTimeSelect(neeYear = false): ShortCuts[] {
  /**当前时间 */
  const currentDate: Date = new Date();

  const shortCuts: ShortCuts[] = [
    {
      text: "最近7天",
      value: () => {
        const end = currentDate;
        const start = new Date();
        start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
        return [start, end];
      },
    },
    {
      text: "最近30天",
      value: () => {
        const end = currentDate;
        const start = new Date();
        start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
        return [start, end];
      },
    },
    {
      text: "最近90天",
      value: () => {
        const end = currentDate;
        const start = new Date();
        start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
        return [start, end];
      },
    },
  ];

  if (neeYear) {
    shortCuts[2] = {
      text: "最近1年",
      value: () => {
        const end = currentDate;
        const start = new Date();
        start.setTime(start.getTime() - 3600 * 1000 * 24 * 365);
        return [start, end];
      },
    };
  }

  return shortCuts;
}

/**正则表达式 ，将首字母更改为大写 */
export function toUpperCaseFirstWord(string: string) {
  return string.replace(/\b([\w|`]+)\b/g, function (word: string) {
    return word.replace(word.charAt(0), word.charAt(0).toUpperCase());
  });
}

/**message loading */
export function messageLoading(message = "数据加载中..."): MessageHandler {
  return ElMessage({
    showClose: true,
    message,
    duration: 0,
    customClass: "loading-message",
  });
}

/**message loading  close*/
export function messageLoadingClose(
  messageLoading: MessageHandler,
  message = "数据加载完成",
  isSuccess = true
) {
  messageLoading?.close();
  ElMessage({
    showClose: true,
    message,
    type: isSuccess ? "success" : "error",
    duration: 1500,
  });
}
/**
 * 开启页面loading,并在某个时间关闭
 * @param {*} timer 设置定关闭时间
 * @param {*} message loading 过程中要展示的提示文字
 */
export function openLoading(message: string, timer: any = 500) {
  const loadingInstance = ElLoading.service({
    lock: true,
    text: message ?? "全力加载中...",
  });

  setTimeout(() => {
    loadingInstance.close();
  }, timer);
}

/**动态增加路由 */
export function addRoute(key: string, type = "Config") {
  const hasRoute = router.hasRoute(`${key}${type}`);
  if (hasRoute) return false;

  router.removeRoute("404"); //先删除路由队尾的404匹配
  router.addRoute({
    path: `/activityCenter/${key}${type}/:templateId/:id`,
    name: `${key}${type}`,
    meta: {
      role: ["admin", "user"],
      keepAlive: false,
    },
    component: () =>
      import(
        /* webpackChunkName: "activityConfig" */ `@/pages/ActivityCenter/Children/${toUpperCaseFirstWord(
          key
        )}Template/${key}${type}.vue`
      ),
  }); //将新路由增加至路由队尾

  router.addRoute({
    path: "/:pathMatch(.*)",
    name: "404",
    meta: {
      role: ["admin", "user"],
      keepAlive: false,
    },
    component: () => import("@/pages/Error/page-not-found.vue"),
  }); //重新缝合404匹配至路由队尾
}

/**根据时间戳计算剩余天数 */
export function transitionTimeSpan(timeSpan: number) {
  const days = Math.floor(timeSpan / (24 * 3600 * 1000)); // 计算出天数
  const remainHours = timeSpan % (24 * 3600 * 1000); // 计算天数后剩余的时间
  const hours = Math.floor(remainHours / (3600 * 1000)); // 计算天数后剩余的小时数
  const remainMinutes = timeSpan % (3600 * 1000); // 计算剩余小时后剩余的毫秒数
  const minutes = Math.floor(remainMinutes / (60 * 1000)); // 计算剩余的分钟数
  const seconds = (timeSpan / 1000) % 60; // 计算剩余分钟后剩余的秒数

  return `${days}天${hours}小时${minutes}分钟${seconds}秒`;
}

/**格式化时间 */
export function formatTime(
  timestamp: number,
  formatStr = "YYYY-MM-DD HH:mm:ss"
) {
  return dayjs(timestamp).format(formatStr);
}

/**展示成功message提示 */
export function showSuccessMessage(message: string) {
  return ElMessage({
    showClose: true,
    message,
    type: "success",
  });
}
/**展示错误message提示 */
export function showErrorMessage(message: string) {
  return ElMessage({
    showClose: true,
    message,
    type: "error",
  });
}
/**展示警告message提示 */
export function showWarningMessage(message: string) {
  return ElMessage({
    showClose: true,
    message,
    type: "warning",
  });
}

/**
 * 纯函数-数组逆扁平化，数组层级加一
 * @param {*} array 需要逆扁平化的数组
 * @param {*} volume 每个2级数组内最大容量
 */
export function combinationArray(array: any[], volume: any = 7) {
  const length = array.length;
  const lineNum =
    length % volume === 0 ? length / volume : Math.floor(length / volume + 1);
  const res: any = [];
  for (let i = 0; i < lineNum; i++) {
    const temp: object = array.slice(i * volume, i * volume + volume);
    res.push(deepCopy(temp));
  }
  return res;
}

/**使用A标签链接方式下载文件 */
export function downloadFileForALabel(URL: string, PARAMS = "") {
  const link = document.createElement("a");
  link.setAttribute("target", "_top"); //_blank  _top  _self
  link.setAttribute("download", "");
  link.setAttribute("href", `${URL}${queryParams(PARAMS)}`);
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link); // 下载完毕删除a标签
}

/**json对象和url参数互转 */
export function queryParams(data: any, isPrefix = true) {
  const prefix = isPrefix ? "?" : "";
  const _result: any = [];
  for (const key in data) {
    const value = data[key];
    // 去掉为空的参数
    if (["", undefined, null].includes(value)) {
      continue;
    }
    if (value.constructor === Array) {
      value.forEach((_value) => {
        _result.push(
          encodeURIComponent(key) + "[]=" + encodeURIComponent(_value)
        );
      });
    } else {
      _result.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
    }
  }
  return _result.length ? prefix + _result.join("&") : "";
}

/**下载blob文件 */
export function downloadedFile(response, filename = "导出数据") {
  const link = document.createElement("a");
  const blobURL = window.URL.createObjectURL(
    new Blob([response], {
      type: "application/msexcel",
    })
  );

  link.style.display = "none";
  link.href = blobURL;
  link.setAttribute("download", `${filename}${formatTime(Date.now())}.xlsx`);
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link); // 下载完毕删除a标签
  window.URL.revokeObjectURL(blobURL);
}

/**用户登录过期后，跳转至登录页面 */
export function redirectUrl() {
  if (process.env.NODE_ENV === "development") return false;

  const redirect_url = `${process.env.VUE_APP_BASE_URL}${process.env.VUE_APP_BASE_URL_PREFIX}/login`;

  const login_url = `https://open.kwaixiaodian.com/oauth/authorize?app_id=ks672162245634397669&redirect_uri=${encodeURIComponent(
    redirect_url
  )}&scope=merchant_distribution,merchant_refund,merchant_item,merchant_order,merchant_shoplive,user_info,merchant_servicemarket,merchant_promotion,merchant_user,merchant_comment&response_type=code`;

  window.location.href = login_url;
}
/**禁用日期组件的时间范围 */
export function disabledDate(time: Date) {
  return (
    time.getTime() > new Date("2030/12/31").getTime() ||
    time.getTime() < new Date("2020/1/1").getTime()
  );
}

/**计算使用时间 */
export function timeTransition(num: number) {
  let returnNum = 0;

  if (num <= 3600000) {
    returnNum = num / 60 / 1000;
    return `领取${returnNum}分钟内有效`;
  } else if (num < 86400000) {
    returnNum = parseInt(`${num / 60000 / 60}`);
    const getMinute = (num - returnNum * 60 * 60 * 1000) / 60000;

    return `领取${returnNum}小时${getMinute ? `${getMinute}分钟` : ""}内有效`;
  } else {
    returnNum = parseInt(`${num / 60000 / 60 / 24}`);
    const getHour = (num - returnNum * 24 * 60 * 60 * 1000) / (60 * 60 * 1000);
    const getMinute =
      (num - returnNum * 24 * 60 * 60 * 1000 - getHour * 60 * 60 * 1000) /
      (60 * 1000);

    return `领取${returnNum}天${getHour ? `${getHour}小时` : ""}${
      getMinute ? `${getMinute}分钟` : ""
    }内有效`;
  }
}

/**
 * 为数字加千位分隔符 - 过滤器 2.0版本
 * @param num
 */
export function SetKiloCharacter(num: number | string) {
  if (!num) return 0;

  if (typeof num === "number") {
    return numSetKiloCharacter(num);
  } else if (typeof num === "string") {
    const res =
      num.split(",").length - 1 ? num : numSetKiloCharacter(parseFloat(num));
    return res;
  } else {
    return num;
  }

  /**number 转string并添加千分位, */
  function numSetKiloCharacter(num) {
    const res = num.toString().replace(/\d+/, function (n) {
      // 先提取整数部分
      return n.replace(/(\d)(?=(\d{3})+$)/g, function ($1) {
        return $1 + ",";
      });
    });
    return res;
  }
}
